// ## 
#include "ModelGenerator.h"
#include "AtomicGenerators.h"
#include "Slices.h"
// ## C++
#include <cassert>

namespace jm4bbx {

	const char* ModelGenerator::END_BOX_NAME = "output_box";

	const char* ModelGenerator::START_BOX_NAME = "input_box";


	int ModelIdGenerator::getNextBoxId() {
		static int boxId = 0;
		return ++boxId;
	}

	int ModelIdGenerator::getNextViaId() {
		static int viaId = 0;
		return ++viaId;
	}


	ModelGenerator::ModelGenerator() {
		addBox(START_BOX_NAME);
		addBox(END_BOX_NAME);
	}



	jm4bbx::BoxDescriptorPtr ModelGenerator::addBox(const std::string& boxName, const std::string& boxParams, int repetition /*= 1*/) {
		BoxDescriptorPtr boxDesc(new BoxDescriptor(boxName, boxParams));
		addBox(boxDesc, repetition);
		return boxDesc;
	}

	jm4bbx::BoxDescriptorPtr ModelGenerator::addBox(const std::string& boxName, int repetition /*= 1*/) {
		return addBox(boxName, "", repetition);
	}

	void ModelGenerator::addBox(const BoxDescriptorPtr& box, int repetition /*= 1*/) {
		for (int i = 0; i < repetition; ++ i) {
			box->addBoxId(idGenerator_.getNextBoxId());
		}
		boxes_.push_back(box);
	}

	std::string ModelGenerator::generateModel() {
		std::stringstream model;

		for (size_t i = 0; i < boxes_.size(); ++i) {
			model << genBox(boxes_[i]);
		}


		for (size_t i = 0; i < slices_.size(); ++i) {
			model << slices_[i]->generateBody(idGenerator_);
		}

		return model.str();
	}

	int ModelGenerator::getModelInputId() const {
		assert(boxes_.size() >= 2);
		return boxes_[0]->getBoxId();
	}

	int ModelGenerator::getModelOutputId() const {
		assert(boxes_.size() >= 2);
		return boxes_[1]->getBoxId();
	}

} // namespacfe jm4bbx 
